////////////////////////////////////////////////////////////////////////////
//
//  Crytek Engine Source File.
//  Shader extension
//  Copyright (C), Crytek Studios, 2001-2004.
// -------------------------------------------------------------------------
//  File name:   PostEffectsLib.cfi
//  Version:     v1.00
//  Created:     13/06/2006 by Tiago Sousa
//  Compilers:   
//  Description: Common post-process utilities library
//
//  Todo: Clean stuff up
//
// -------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////

//////////////////////////////// Common constants ////////////////

// Common vertex and pixel shader params 
//    - use for explicitly setting values from code

float4 vsParams[16];
float4 psParams[16];

float4   RotGridScreenOffset : PB_RotGridScreenOff;
float   AnimGenParams = { PB_time 1.0 };
float4   WorldViewPos  : PB_CameraPos;

float4   CameraUp : PB_CameraUp;
float4   CameraRight : PB_CameraRight;
float4   CamFront : PB_CameraFront;

float4  ScrSize : PB_ScreenSize;

// x, y, z - unused, w - particle lifetime
float4  vScrParticleInfo;
	
#if D3D10 && !PS3
	#define RAIN_OCC_MAP_SIZE 512
#else
	#define RAIN_OCC_MAP_SIZE 256
#endif

//////////////////////////////// Common samplers ////////////////

// Use when explicitly binding from code (_tex to void name colision)
sampler2D _tex0 : register(s0);
sampler2D _tex1 : register(s1);
sampler2D _tex2 : register(s2);
sampler2D _tex3 : register(s3);
sampler2D _tex4 : register(s4);
sampler2D _tex5 : register(s5);
sampler2D _tex6 : register(s6);
sampler2D _tex7 : register(s7);
sampler2D _tex8 : register(s8);
sampler2D _tex9 : register(s9);
sampler2D _texA : register(s10);
sampler2D _texB : register(s11);
sampler2D _texC : register(s12);
sampler2D _texD : register(s13);
sampler2D _texE : register(s14);
sampler2D _texF : register(s15);

#if D3D10
Texture2D _tex3_d3d10 : register(s3);
#endif

samplerCUBE _cubetex0 : register(s0);
samplerCUBE _cubetex1 : register(s1);
samplerCUBE _cubetex2 : register(s2);
samplerCUBE _cubetex3 : register(s3);
samplerCUBE _cubetex4 : register(s4);
samplerCUBE _cubetex5 : register(s5);
samplerCUBE _cubetex6 : register(s6);
samplerCUBE _cubetex7 : register(s7);

// Use for auto binding
sampler2D screenMapSampler : register (s0)
{
  Texture = $BackBuffer;
  MinFilter = POINT;
  MagFilter = POINT;
  MipFilter = POINT; 
  AddressU = Clamp;
  AddressV = Clamp;	
};

sampler2D depthMapSampler  : register (s1)
{
  Texture = $ZTarget;
  MinFilter = POINT;
  MagFilter = POINT;
  MipFilter = POINT; 
  AddressU = Clamp;
  AddressV = Clamp;	
};

sampler2D screenMapScaledSampler_d2  : register (s2)
{
  Texture = $BackBufferScaled_d2;
  MinFilter = LINEAR;
  MagFilter = LINEAR;
  MipFilter = POINT; 
  AddressU = Clamp;
  AddressV = Clamp;	
};

sampler2D screenMapScaledSampler_d4  : register (s3)
{
  Texture = $BackBufferScaled_d4;
  MinFilter = LINEAR;
  MagFilter = LINEAR;
  MipFilter = POINT; 
  AddressU = Clamp;
  AddressV = Clamp;	
};

sampler2D screenMapScaledSampler_d8  : register (s4)
{
  Texture = $BackBufferScaled_d8;
  MinFilter = LINEAR;
  MagFilter = LINEAR;
  MipFilter = POINT; 
  AddressU = Clamp;
  AddressV = Clamp;	
};

sampler2D screenTargetSampler : register (s0)
{
  Texture = $SceneTarget;
  MinFilter = POINT;
  MagFilter = POINT;
  MipFilter = POINT; 
  AddressU = Clamp;
  AddressV = Clamp;	
};

//////////////////////////////// Common vertex shader stuff ////////////////

struct pixout_MRT
{
  float4 Color  : COLOR0;
  float4 Color1 : COLOR1;
};

struct vtxIn
{
  IN_P
  IN_TBASE
	IN_C0
};

struct vtxInWPOS
{
  IN_P
  IN_TBASE
  float3 CamVec : TEXCOORD1;
};

struct vtxOut
{
  float4 HPosition  : POSITION;
  float4 baseTC     : TEXCOORD0;
};

struct vtxOutWPOS
{
  float4 HPosition   : POSITION;
  float4 baseTC      : TEXCOORD0;
  float4 CamVec      : TEXCOORD1;
};

///////////////// vertex shader //////////////////

vtxOut BaseVS(vtxIn IN)
{
  vtxOut OUT = (vtxOut)0; 

  float4 vPos = IN.Position;
  OUT.HPosition = mul(vpMatrix, vPos);  
  OUT.baseTC.xy = IN.baseTC.xy;

  // output with correct aspect ratio into wz
  OUT.baseTC.wz = (IN.baseTC.xy -0.5 ) * float2(0.75*(ScrSize.x/ScrSize.y), 1.0) + 0.5;

  return OUT;
}

///////////////// vertex shader //////////////////

vtxOutWPOS BaseWPOSVS(vtxInWPOS IN)
{
  vtxOutWPOS OUT = (vtxOutWPOS)0; 

  float4 vPos = IN.Position;
  OUT.HPosition = mul(vpMatrix, vPos);  
  OUT.baseTC.xy = IN.baseTC.xy;
  OUT.CamVec.xyz = IN.CamVec;

  return OUT;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

// Color grading/charts tex lookup
void TexColorChart2D(in sampler2D chartSampler, inout half3 cImage)
{
	const float chartDim	= 16.0;
	const float3 scale = float3(chartDim - 1.0, chartDim - 1.0, chartDim - 1.0) / chartDim;
	const float3 bias = float3(0.5, 0.5, 0.0) / chartDim;

	//cImage = float3(0.5, 1.0, 4.0 / chartDim); // debug lookup color to test addressing of "unwrapped" chart slices
	
	float3 lookup = saturate(cImage) * scale + bias;
	
	// convert input color into 2d color chart lookup address 
	float slice = lookup.z * chartDim;	
	float sliceFrac = frac(slice);	
	float sliceIdx = slice - sliceFrac;
	
	lookup.x = (lookup.x + sliceIdx) / chartDim;
	
 	// lookup adjacent slices
 	float3 col0 = tex2D(chartSampler, lookup.xy); 	
 	lookup.x += 1.0 / chartDim;
 	float3 col1 = tex2D(chartSampler, lookup.xy);

	// linearly blend between slices 	 	
	cImage = col0 + (col1 - col0) * sliceFrac;
 	//cImage = sliceFrac;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

#if D3D11

Texture2DMS<float4> _tex0MS : register(s0);
Texture2DMS<float4> _tex1MS : register(s1);
Texture2DMS<float4> _tex2MS : register(s2);
Texture2DMS<float4> _tex3MS : register(s3);

half4 GetTargetIndexMS( int nIndex, float2 baseTC, int NumSamples, int nCurrSample ) 
{
	int3 vPixCoord = int3( baseTC * PS_ScreenSize.xy, 0);
	if( nIndex == 0 )
		return _tex0MS.Load(vPixCoord, nCurrSample);
	if( nIndex == 1 )
	  return _tex1MS.Load(vPixCoord, nCurrSample);
	if( nIndex == 2 )
		return _tex2MS.Load(vPixCoord, nCurrSample);
	if( nIndex == 3 )
		return _tex3MS.Load(vPixCoord, nCurrSample);
}

#endif

/////////////////////// eof ///
